#include "pmem.h"
#include <stdio.h>
#include <getopt.h>
#include <stdlib.h>
#include "common.h"
#include "ftrace.h"
void init_mem();
void init_device();
void init_sdb();
void init_disasm(const char *triple);
void init_difftest(char *ref_so_file, long img_size,int port);
void sdb_set_batch_mode();
static char *img_file = NULL;
static char *elf_file = NULL;
static char *log_file = NULL;
static char *diff_so_file = NULL;
static int difftest_port = 1234;
static long load_img() {
	if (img_file == NULL) {
		//Log("No image is given. Use the default build-in image.");
		return 4096; // built-in image size
	}
	FILE *fp = fopen(img_file, "rb");
	assert(fp);
	fseek(fp, 0, SEEK_END);
	long size = ftell(fp);
	//Log("The image is %s, size = %ld", img_file, size);
	fseek(fp, 0, SEEK_SET);
	int ret = fread(guest_to_host(RESET_VECTOR), size, 1, fp);
	assert(ret == 1);
	fclose(fp);
	return size;
}
static int parse_args(int argc, char *argv[]) {
	const struct option table[] = {
		{"batch"    , no_argument      , NULL, 'b'},
		{"log"      , required_argument, NULL, 'l'},
		{"diff"     , required_argument, NULL, 'd'},
		{"port"     , required_argument, NULL, 'p'},
		{"elf"      , required_argument, NULL, 'e'},
		{"help"     , no_argument      , NULL, 'h'},
		{0          , 0                , NULL,  0 },
	};
	int o;
	while ( (o = getopt_long(argc, argv, "-bhl:d:p:e:", table, NULL)) != -1) {
		switch (o) {
			case 'b': sdb_set_batch_mode(); break;
			case 'p': sscanf(optarg, "%d", &difftest_port); break;
			case 'l': log_file = optarg; break;
			case 'd': diff_so_file = optarg; break;
			case 'e': elf_file = optarg;break; 
			case 1: img_file = optarg; return 0;
			default:
				printf("Usage: %s [OPTION...] IMAGE [args]\n\n", argv[0]);
				printf("\t-b,--batch              run with batch mode\n");
				printf("\t-l,--log=FILE           output log to FILE\n");
				printf("\t-d,--diff=REF_SO        run DiffTest with reference REF_SO\n");
				printf("\t-p,--port=PORT          run DiffTest with port PORT\n");
				printf("\n");
				exit(0);
			}
	}
return 0;
}
void init_monitor(int argc, char *argv[]){
	parse_args(argc,argv);
	init_log(log_file);
	Log("successfully get args");
	init_mem();
	Log("successfully init_mem");
#ifdef CONFIG_DEVICE
	init_device();
#endif
	long img_size = load_img();
#ifdef CONFIG_FTRACE
	load_elf(elf_file);
#endif
#ifdef CONFIG_DIFFTEST
	init_difftest(diff_so_file,img_size,difftest_port);
#endif
	Log("successfully load img,img_file:%s,imgsize = %ld",img_file,img_size);
	init_sdb();
	init_disasm("riscv64-pc-linux-gnu");
}
